Add a configuration option for HTTP timeouts
authorAlex Crichton <alex@alexcrichton.com>
Wed, 14 Jan 2015 18:11:08 +0000 (10:11 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 16 Jan 2015 16:45:07 +0000 (08:45 -0800)
Closes #1087

src/cargo/core/dependency.rs
src/cargo/ops/registry.rs
src/cargo/util/config.rs
src/doc/config.md
tests/test_bad_config.rs
tests/test_cargo_compile.rs

index a26e7eace1e1c7937ed7d510262f4e9e8c9b1a51..952c759faa705876b5756d1a860dc31dd03a9dcb 100644 (file)
@@ -31,16 +31,6 @@ pub enum Kind {
 
 impl Dependency {
     /// Attempt to create a `Dependency` from an entry in the manifest.
-    ///
-    /// ## Example
-    ///
-    /// ```
-    /// use cargo::core::SourceId;
-    /// use cargo::core::Dependency;
-    ///
-    /// Dependency::parse("color", Some("1.*"),
-    ///                   &SourceId::for_central().unwrap()).unwrap();
-    /// ```
     pub fn parse(name: &str,
                  version: Option<&str>,
                  source_id: &SourceId) -> CargoResult<Dependency> {
index 567218cdfbf373e8ffe1ec03c9f12a259dd7f47c..a554259cc963f6ec67411431c12ad520fcffb156 100644 (file)
@@ -161,10 +161,16 @@ pub fn registry(config: &Config,
 
 /// Create a new HTTP handle with appropriate global configuration for cargo.
 pub fn http_handle(config: &Config) -> CargoResult<http::Handle> {
-    Ok(match try!(http_proxy(config)) {
-        Some(proxy) => http::handle().proxy(proxy),
-        None => http::handle(),
-    })
+    let handle = http::handle();
+    let handle = match try!(http_proxy(config)) {
+        Some(proxy) => handle.proxy(proxy),
+        None => handle,
+    };
+    let handle = match try!(http_timeout(config)) {
+        Some(timeout) => handle.timeout(timeout as usize),
+        None => handle,
+    };
+    Ok(handle)
 }
 
 /// Find a globally configured HTTP proxy if one is available.
@@ -188,6 +194,14 @@ pub fn http_proxy(config: &Config) -> CargoResult<Option<String>> {
     Ok(os::getenv("HTTP_PROXY"))
 }
 
+pub fn http_timeout(config: &Config) -> CargoResult<Option<i64>> {
+    match try!(config.get_i64("http.timeout")) {
+        Some((s, _)) => return Ok(Some(s)),
+        None => {}
+    }
+    Ok(os::getenv("HTTP_TIMEOUT").and_then(|s| s.parse()))
+}
+
 pub fn registry_login(config: &Config, token: String) -> CargoResult<()> {
     let RegistryConfig { index, token: _ } = try!(registry_configuration(config));
     let mut map = HashMap::new();
index 4dc87ddfcc135951cf38cdf9b58ce5dd5954cebb..46bb6915d289d521020d10a22420cda1e9a05cfe 100644 (file)
@@ -108,6 +108,7 @@ impl<'a> Config<'a> {
                         None => return Ok(None),
                     }
                 }
+                CV::Integer(_, ref path) |
                 CV::String(_, ref path) |
                 CV::List(_, ref path) |
                 CV::Boolean(_, ref path) => {
@@ -140,6 +141,14 @@ impl<'a> Config<'a> {
         }
     }
 
+    pub fn get_i64(&self, key: &str) -> CargoResult<Option<(i64, Path)>> {
+        match try!(self.get(key)) {
+            Some(CV::Integer(i, path)) => Ok(Some((i, path))),
+            Some(val) => self.expected("integer", key, val),
+            None => Ok(None),
+        }
+    }
+
     pub fn expected<T>(&self, ty: &str, key: &str, val: CV) -> CargoResult<T> {
         val.expected(ty).map_err(|e| {
             human(format!("invalid configuration for key `{}`\n{}", key, e))
@@ -183,6 +192,7 @@ pub enum Location {
 
 #[derive(Eq,PartialEq,Clone,RustcDecodable)]
 pub enum ConfigValue {
+    Integer(i64, Path),
     String(String, Path),
     List(Vec<(String, Path)>, Path),
     Table(HashMap<String, ConfigValue>, Path),
@@ -192,9 +202,9 @@ pub enum ConfigValue {
 impl fmt::Show for ConfigValue {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            CV::String(ref string, ref path) => {
-                write!(f, "{} (from {})", string, path.display())
-            }
+            CV::Integer(i, ref path) => write!(f, "{} (from {:?})", i, path),
+            CV::Boolean(b, ref path) => write!(f, "{} (from {:?})", b, path),
+            CV::String(ref s, ref path) => write!(f, "{} (from {:?})", s, path),
             CV::List(ref list, ref path) => {
                 try!(write!(f, "["));
                 for (i, &(ref s, ref path)) in list.iter().enumerate() {
@@ -204,9 +214,6 @@ impl fmt::Show for ConfigValue {
                 write!(f, "] (from {:?})", path)
             }
             CV::Table(ref table, _) => write!(f, "{:?}", table),
-            CV::Boolean(b, ref path) => {
-                write!(f, "{} (from {})", b, path.display())
-            }
         }
     }
 }
@@ -221,6 +228,7 @@ impl Encodable for ConfigValue {
             }
             CV::Table(ref table, _) => table.encode(s),
             CV::Boolean(b, _) => b.encode(s),
+            CV::Integer(i, _) => i.encode(s),
         }
     }
 }
@@ -230,6 +238,7 @@ impl ConfigValue {
         match toml {
             toml::Value::String(val) => Ok(CV::String(val, path.clone())),
             toml::Value::Boolean(b) => Ok(CV::Boolean(b, path.clone())),
+            toml::Value::Integer(i) => Ok(CV::Integer(i, path.clone())),
             toml::Value::Array(val) => {
                 Ok(CV::List(try!(val.into_iter().map(|toml| {
                     match toml {
@@ -255,6 +264,7 @@ impl ConfigValue {
     fn merge(&mut self, from: ConfigValue) -> CargoResult<()> {
         match (self, from) {
             (&mut CV::String(..), CV::String(..)) |
+            (&mut CV::Integer(..), CV::Integer(..)) |
             (&mut CV::Boolean(..), CV::Boolean(..)) => {}
             (&mut CV::List(ref mut old, _), CV::List(ref mut new, _)) => {
                 let new = mem::replace(new, Vec::new());
@@ -278,6 +288,13 @@ impl ConfigValue {
         Ok(())
     }
 
+    pub fn i64(&self) -> CargoResult<(i64, &Path)> {
+        match *self {
+            CV::Integer(i, ref p) => Ok((i, p)),
+            _ => self.expected("integer"),
+        }
+    }
+
     pub fn string(&self) -> CargoResult<(&str, &Path)> {
         match *self {
             CV::String(ref s, ref p) => Ok((s.as_slice(), p)),
@@ -312,12 +329,14 @@ impl ConfigValue {
             CV::List(..) => "array",
             CV::String(..) => "string",
             CV::Boolean(..) => "boolean",
+            CV::Integer(..) => "integer",
         }
     }
 
     pub fn definition_path(&self) -> &Path {
         match *self  {
             CV::Boolean(_, ref p) |
+            CV::Integer(_, ref p) |
             CV::String(_, ref p) |
             CV::List(_, ref p) |
             CV::Table(_, ref p) => p
@@ -333,6 +352,7 @@ impl ConfigValue {
         match self {
             CV::Boolean(s, _) => toml::Value::Boolean(s),
             CV::String(s, _) => toml::Value::String(s),
+            CV::Integer(i, _) => toml::Value::Integer(i),
             CV::List(l, _) => toml::Value::Array(l
                                           .into_iter()
                                           .map(|(s, _)| toml::Value::String(s))
index e7b6e33e249bbcae60aea467f3ec7124b358062f..af008b1b193abcece2490e48256d98636470b164 100644 (file)
@@ -72,5 +72,6 @@ index = "..."   # URL of the registry index (defaults to the central repository)
 token = "..."   # Access token (found on the central repo's website)
 
 [http]
-proxy = "..."   # HTTP proxy to use for HTTP requests (defaults to none)
+proxy = "..."     # HTTP proxy to use for HTTP requests (defaults to none)
+timeout = 30000   # Timeout for each HTTP request, in milliseconds
 ```
index 8ecc23f0ae5e5e055d3e9f7e63e3911d1732d63e..3e644293c89c847e9d9ca7107172b5105c3ddea8 100644 (file)
@@ -32,7 +32,7 @@ test!(bad2 {
         .file("src/lib.rs", "")
         .file(".cargo/config", r#"
               [http]
-                proxy = 3
+                proxy = 3.0
         "#);
     assert_that(foo.cargo_process("publish").arg("-v"),
                 execs().with_status(101).with_stderr("\
@@ -48,7 +48,7 @@ Caused by:
   failed to parse key `proxy`
 
 Caused by:
-  found TOML configuration value of unknown type `integer`
+  found TOML configuration value of unknown type `float`
 "));
 });
 
index 91707762a3a188efcf9c9ee4dc55988b0dd88789..162ccb36ee40712de9b5d9bc5d14907e2be65991 100644 (file)
@@ -1401,7 +1401,7 @@ test!(bad_cargo_config {
 Couldn't load Cargo configuration
 
 Caused by:
-  could not parse TOML configuration; path=[..]
+  could not parse TOML configuration in `[..]`
 
 Caused by:
   could not parse input as TOML